package com.example.sxt_practise.thread;

/**
 * 生产者消费者模型
 * @author gaofeng
 * @date 2022年05月28日 11:40
 */
public class ProductConsumerTest {
    public static void main(String[] args) {
        Container container = new Container() ;
        new Productor(container).start();
        new Consumer(container).start();
    }
}

/**
 * 生产者和消费者共享的资源
 */
class Chicken {
    Integer id ;

    public Chicken(Integer id) {
        this.id = id;
    }
}

/**
 * 生产者
 */
class Productor extends Thread {

    Container container ;

     Productor(Container container) {
        this.container = container ;
    }

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            container.push(new Chicken(i));
            System.out.println("生产了" + i + "只鸡");
        }
    }
}

/**
 * 消费者
 */
class Consumer extends Thread {
    Container container ;

    Consumer(Container container) {
        this.container = container ;
    }

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("消费了" + container.pop().id + "只鸡");
        }
    }
}

/**
 * 缓冲区
 */
class Container {

    Chicken[] chickens = new Chicken[10] ;

    /**
     * 计数器
     */
    Integer count = 0;

    /**
     * 生产者
     */
    public synchronized void push(Chicken chicken) {
        // 如果容器满了
        if (count == chickens.length) {
            // 通知消费者消费,生产者等待
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        //没满,放入产品
        chickens[count] = chicken ;
        count++ ;
        // 通知消费者消费
        this.notifyAll();
    }

    /**
     * 消费者
     */
    public synchronized Chicken pop() {
        // 判断是否能消费
        if (count == 0) {
            // 等待生产者生产,消费者等待
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        // 能消费
        count-- ;
        Chicken chicken = chickens[count];
        // 通知生产者生产
        this.notifyAll();
        return chicken ;
    }
}

